# Root Configuration

The root is the top-level component within Puck. It:

1. Renders a single wrapper around your other components. This can be overwritten with a `render` function.
2. Stores meta data, like the page title. This can be extended with `fields`.

Configuring the root is similar to [configuring components](component-configuration).

## The root `render` function

Use the [`root` parameter](/docs/api-reference/configuration/config#root) to specify a [`render` function](/docs/api-reference/configuration/component-config#renderprops):

```tsx showLineNumbers copy {10-12}
const config = {
  components: {
    HeadingBlock: {
      render: () => {
        return <h1>Hello, world</h1>;
      },
    },
  },
  root: {
    render: ({ children }) => {
      return <div>{children}</div>;
    },
  },
};
```

The root `render` function will wrap all of the components. `children` is a node containing the nested components.

If you don't render `children`, your components will not be rendered unless you define another [slot](/docs/api-reference/fields/slot).

### Example output

Given a minimal data payload containing one **HeadingBlock**

```json copy
{
  "content": [
    {
      "type": "HeadingBlock",
      "props": {
        "id": "HeadingBlock-1234"
      }
    }
  ],
  "root": {}
}
```

the example config will render HTML nodes like this:

```html
<!-- root render -->
<div>
  <!-- HeadingBlock render -->
  <h1>Hello, world</h1>

  <!-- Remaining nodes -->
</div>
```

## Adding fields

Root fields provide user input to the root render method, and can be used to store metadata.

By default, `root` is configured with a `title` text field:

```tsx showLineNumbers copy /title/
const config = {
  // ...
  root: {
    render: ({ children, title }) => {
      return (
        <div>
          <h1>{title}</h1>
          {children}
        </div>
      );
    },
  },
};
```

You can override the default field configuration by providing custom [Fields](/docs/api-reference/fields) to the [`fields` parameter](/docs/api-reference/configuration/component-config#fields):

```tsx showLineNumbers copy {4-7} /description/2,3
const config = {
  // ...
  root: {
    fields: {
      title: { type: "text" }, // You need to redefine the `title` field if we want to retain it
      description: { type: "textarea" },
    },
    render: ({ children, title, description }) => {
      return (
        <div>
          <h1>{title}</h1>
          <p>{description}</p>
          {children}
        </div>
      );
    },
  },
};
```

When the user modifies the inputs, the editor will produce a data payload like this:

```json copy {6-9}
{
  "content": [
    // ...
  ],
  "root": {
    "props": {
      "title": "Hello, world",
      "description": "Lorem ipsum"
    }
  }
}
```

### TypeScript

Generic types can be passed to the `Config` type to strictly type your root configuration:

```tsx copy {1,3-5} /RootProps/2
import type { Config } from "@measured/puck";

type RootProps = {
  description: string;
};

const config: Config<{}, RootProps> = {
  // ...
};
```

## Setting default props

Provide an object to the [`defaultProps`](/docs/api-reference/configuration/component-config#fields) parameter to configure default props for the root fields:

```tsx showLineNumbers copy {8-11}
const config = {
  // ...
  root: {
    fields: {
      title: { type: "text" },
      description: { type: "textarea" },
    },
    defaultProps: {
      title: "Hello, world",
      description: "Lorem ipsum",
    },
    render: ({ children, title, description }) => {
      return (
        <div>
          <h1>{title}</h1>
          <p>{description}</p>
          {children}
        </div>
      );
    },
  },
};
```

Unlike [default parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters), `defaultProps` are stored in the data payload and will populate the Puck fields.
